<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
        tapable.js
        1.基本介绍
            Sync（同步）
                SyncHook 并行，循环所有的钩子并执行 用forEach
                SyncBailHook 串行，执行结果为undefined，就执行后面的钩子，否则就停止 用do while
                SyncWaterfallHook 串行，将执行结果给后面，用reduce
                SyncLoopHook 串行，执行结果为undefined，就执行后面的钩子，否则一直执行当前钩子 用forEach + do while
                    使用tap注册，使用call触发
            AsyncParallel（异步，并行）
                AsyncParallelHook 并行
                    使用tapAsync注册，使用callAsync触发，利用cb去统计函数执行次数实现
                    使用tapPromise注册，使用promise触发，利用Promise.all实现
                    失败可以提前结束，即提前执行callAsync中的回调
                        cb中有参数
                            参数为null、undefined、false成功；
                            参数为其他，提前失败；
                        cb中无参数，执行完所有cb，再执行callAsync中的回调
                AsyncParallelBailHook 并行
                    成功或失败都可以提交结束，即提前执行callAsync中的回调
                        cb中有参数
                            参数为null、undefined、false提前成功；
                            参数为其他，提前失败；
                        cb中无参数，执行完所有cb，再执行callAsync中的回调
            AsyncSeries（异步，串行）
                AsyncSeriesHook
                AsyncSeriesBailHook
                AsyncSeriesWaterfallHook
            总得来说
                并行用count，Promise.all，Promise.race 实现
                串行用洋葱，reduce 实现

        2.类型理解
            a.基本钩子：简单调用传进去的函数
            b.Waterfall：函数返回值给下一个函数
            c.Bail：函数返回值为undefined，就执行下一个函数，否则停止
            d.Loop：函数返回值为undefined，就执行下一个函数，否则一直执行

        3.注册及调用方式
            a.tap注册 call调用
            b.tapAsync注册 callAsync调用
            c.tapPromise注册 promise调用
    */
</script>
</body>
</html>